package cn.fufeiii.bt.demo.globallock;

import cn.fufeiii.bt.common.aspect.lock.GlobalLock;
import cn.fufeiii.bt.common.util.result.CommonResult;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author FuFei
 */
@Slf4j
@RestController
@RequestMapping("/gl")
public class LockController {

    @GlobalLock(key = "'test:' + #key", defaultFallback = "defaultFallback")
    @GetMapping("/t1")
    public CommonResult<String> t1(String key, Integer t) {
        log.info("t1...");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
        }
        if (t > 0) {
            throw new RuntimeException("业务异常");
        }
        return CommonResult.success();
    }

    @GlobalLock(key = "'test:' + #key", fallback = "fallback")
    @GetMapping("/t2")
    public CommonResult<String> t2(String key, Integer t) {
        log.info("t2...");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
        }
        if (t > 0) {
            throw new IllegalStateException("业务异常");
        }
        return CommonResult.success();
    }

    /**
     * 优先级 fallback > defaultFallback
     */
    @GlobalLock(key = "'test:' + #key", fallback = "fallback", defaultFallback = "defaultFallback")
    @GetMapping("/t3")
    public CommonResult<String> t3(String key, Integer t) {
        log.info("t3...");
        if (t > 0) {
            throw new IllegalStateException("业务异常");
        }
        return CommonResult.success();
    }

    @GlobalLock(prefix = "test:sss", key = {"#param.k1", "#param.k2"}, defaultFallback = "defaultFallback")
    @GetMapping("/t4")
    public CommonResult<String> t4(@RequestBody Param param) {
        log.info("t4...");
        try {
            TimeUnit.SECONDS.sleep(param.getT());
        } catch (InterruptedException e) {
        }
        if (param.getT() > 0) {
            throw new IllegalStateException("业务异常");
        }
        return CommonResult.success();
    }

    @GlobalLock(prefix = "test:sss", key = {"#param.k1", "#param.k2"}, defaultFallback = "defaultFallback")
    @GetMapping("/t41")
    public CommonResult<String> t41(@RequestBody Param param) {
        log.info("t41...");
        try {
            TimeUnit.SECONDS.sleep(param.getT());
        } catch (InterruptedException e) {
        }
        if (param.getT() > 0) {
            throw new IllegalStateException("业务异常");
        }
        return CommonResult.success();
    }

    public CommonResult<String> fallback(String key, Integer t, RuntimeException e) {
        log.warn("fallback 出现异常 --> {} {}", e.getClass().getSimpleName(), e.getMessage());
        log.info("打印原方法入参:{}", Arrays.asList(key, String.valueOf(t)));
        return CommonResult.success("fallback");
    }


    public CommonResult<String> defaultFallback(RuntimeException e) {
        log.warn("defaultFallback 出现异常 --> {} {}", e.getClass().getSimpleName(), e.getMessage());
        return CommonResult.success("defaultFallback");
    }

    @Data
    public static class Param {
        List<String> k1;
        List<String> k2;
        Integer t;
    }
}
